package cn.le.io;

import java.io.*;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

/**
 *
 * Preferences api与对象序列化相比，与对象持久性更密切，因为它可以自动存储和读取信息，
 * 不过，它只能用于小的，受限的数据集合，我们只能存储基本类型和字符串，并且每个字符串的存储长度不能超过8k，
 * preferences api用于存储和读取用户偏好以及程序配置想设置。
 *
 * Preferences是一个键-值集合（类似映射），存储在节点层次结构中，尽管节点层次结构可用来创建更复杂的结构，
 * 但是通常是创建以你的类名命名的单一节点，然后将信息存储与其中
 *
 */
public class PreferencesDemo {


    public static void main(String[] args) throws BackingStoreException {

        Preferences prefs = Preferences.userNodeForPackage(PreferencesDemo.class);
        System.out.println(prefs.absolutePath());
        //将指定首选项节点返回到此节点所在的同一树中，如果此节点及其祖先已经不存在，则创建它们。
        prefs.node("aaa");
        //返回此首选项节点相对于此节点的子节点名称。
        for (String str:prefs.childrenNames()) {
            System.out.println(str);
        }
        /*prefs.put("Location","oz");
        prefs.put("Footwar","Ruby Slipers");
        prefs.putInt("Companions",4);
        prefs.putBoolean("are there witches?" ,true);

        int usageCount = prefs.getInt("UsageCount",0);
        usageCount++;
        prefs.putInt("UsageCOunt",usageCount);*/
       /* for (String key:prefs.keys()) {
            System.out.println(key+":"+prefs.get(key,null));
        }*/
    }

    /**
     * 将对像转换为数组
     * @param obj
     * @return
     */
    public byte[] getBytes(Object obj) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(obj);
        return baos.toByteArray();

    }

    /**
     * 将byte数组转换为对象
     * @param raw
     * @return
     */
    public static Object getObject(byte[] raw) throws IOException, ClassNotFoundException {
        ByteArrayInputStream bin = new ByteArrayInputStream(raw);
        ObjectInputStream oin = new ObjectInputStream(bin);
        return oin.readObject();
    }

    /**
     * preferences 对可以存储在它里面的数据大小有限制，具体字符串限制为MAX_VALUE_LENGTH字符，
     * 字节数组限制为MAX_VALUE_LENGTH长度75%,因为字节数组是通过编码为字符串存储的
     *
     * 另一方面，一个对象可以为任意大，所以我们需要将它拆分为几部分，当然，最容易的方法肯定是将它转换
     * 为一个字节数组，然后就字节数组拆开
     */
    static int  pieceLength = Preferences.MAX_VALUE_LENGTH * (3/4);
    public static byte[][] breakIntPieces(byte[] raw)
    {
        int numPieces = (raw.length + pieceLength -1) / pieceLength;
        byte pieces[][] = new byte[numPieces][];
        for (int i = 0; i < numPieces; i++) {
            int startByte = i * pieceLength;
            int endbyte = startByte+pieceLength;
            if(endbyte > raw.length)
            {
                endbyte = raw.length;
            }
            int length = endbyte - startByte;
            pieces[i] = new byte[length];
            System.arraycopy(raw,startByte,pieces[i],0,length);
        }
        return pieces;
    }
}
